
/*
WebSocket:
https://pub-web.flutter-io.cn/packages/web_socket_channel/install

依赖:
dependencies:
  web_socket_channel: ^3.0.2
引入:
import 'package:web_socket_channel/web_socket_channel.dart';

 */
import 'dart:async';

import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:xsdk_flutter/xsdk/operation/x_mixin_release.dart';
import 'package:xsdk_flutter/xsdk/utils/socket/support/x_socket_notify_callback.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_log.dart';

typedef XWebSocketConnectStatusCallback = void Function(
    {
    required bool isConnected,
    dynamic name,
    dynamic url,
    }
    );

typedef XWebSocketReceiveMessageCallback = void Function(dynamic msg);

class XWebSocketAPI with XMixinRelease{

  String url;

  XWebSocketConnectStatusCallback callback_connectStatus;
  XWebSocketReceiveMessageCallback callback_receiveMessage;


  WebSocketChannel? channel;

  /*
  url='ws://example.com'
  url='wss://example.com'
   */
  XWebSocketAPI({
    required this.url,
    required this.callback_connectStatus,
    required this.callback_receiveMessage
});

  //1.连接服务器
  connect() async{

    try{

      final wsUrl = Uri.parse(url);
      channel = WebSocketChannel.connect(wsUrl);
      await channel!.ready;
      XLogUtils.printLog('---WebSocketChannel connect ok');
      callback_connectStatus(isConnected: true,url: url);

      channel!.stream.listen(
              (message) {
            XLogUtils.printLog('---websocket,接收msg=$message');
            callback_receiveMessage(message);
          },
          onError: (e){
            XLogUtils.printLog('---websocket,listen, onError: $e');
          },
          onDone: (){
            XLogUtils.printLog('---websocket,listen,onDone()');
          }
      );

    }catch(e){
      XLogUtils.printLog('---websocket,connect err: $e');
      _handleSocketDisconnect();
    }

  }

  //2.关闭连接
  @override
  void xRelease() {
    //释放资源
    XLogUtils.printLog('---websocket xRelease');

    _isAutoReconnect=false;

    try {
      channel?.sink.close();
      _timer?.cancel();
    }catch (error) {
      //
    }finally{
      _timer = null;
    }

  }


  //3.发送数据
  sendMsg(String msg) async{
    channel?.sink.add(msg);
  }


  ///////////////////////////////////////////////////////////////////////////

  Timer? _timer;
  bool _isAutoReconnect=true;

  void _handleSocketDisconnect(){

    XSocketDeviceNotifyCallback.instance.webSocketDeviceConnectStatusCallback(false,url);


    //自动重连
    if(_isAutoReconnect){
      _timer ??= Timer(const Duration(seconds: 2),(){
        //
        XLogUtils.printLog('---自动重连: websocket= $url');
        //
        connect();
        //
        _timer?.cancel();
        _timer = null;
      }
      );
    }



  }





}
